module PcrWebApps
  module Addresses
    def self.included(base)
      base.extend ClassMethods
    end

    module ClassMethods
      def acts_as_address(options={})
        configuration = { :force_street => false,
                          :force_phone => false}
        configuration.update(options) if options.is_a?(Hash)
        class_eval do
          validates_presence_of :city, :state, :zip_code
          validates_presence_of :line1 if configuration[:force_street]
          validates_presence_of :phone_number if configuration[:force_phone]
          validates_length_of :line1, :maximum => 256, :unless => Proc.new{|x| x.line1.nil?}
          validates_length_of :line2, :maximum => 256, :allow_nil => true
          validates_length_of :city, :maximum => 128, :unless => Proc.new{|x| x.city.nil?}
          validates_length_of :state, :maximum => 2, :unless => Proc.new{|x| x.state.nil?}
          validates_format_of :zip_code,
                              :with => /^\d{5}([\-]\d{4})?$/,
                              :message => "is invalid",
                              :unless => Proc.new{|x| x.zip_code.blank?}
          validates_format_of :phone_number,
                              :with => /^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4}$/,
                              #Conforms to NANP A-digit and D-digit requirements (ANN-DNN-NNNN). 
                              #Area Codes 001-199 are not permitted; 
                              #Central Office Codes 001-199 are not permitted.
                              :message => "is missing or invalid",
                              :unless => Proc.new{|x| (configuration[:force_phone] ? x.phone_number.nil? : x.phone_number.blank?)} 
          #belongs_to :zip_code, :foreign_key => :zip_code

          before_validation_on_create :tweak_line1 unless configuration[:force_street]
          before_validation_on_create :tweak_phone unless configuration[:force_phone]
          attr_accessible :line1, :line2, :city, :state, :zip_code, :phone_number, :created_at,
              :updated_at

private
          def tweak_line1
            self.line1 = "" if line1.nil? 
          end
          def tweak_phone
            self.phone_number = "" if phone_number.nil?
          end
        end
      end
    end
  end
end
